<?php
require_once '../vendor/autoload.php';
require_once '../utils/common.php';

try {
    $redis = get_redis();
} catch (RedisException $e) {
    exit('redis 连接失败: ' . $e->getMessage());
}

// 模拟一个抽奖的场景，1秒钟内最多可以支持5次抽奖请求，超过这个数量，提示 活动太火爆了，请稍后再试
$microtime_limit = 1000 * 1000; // 1秒, 这里以微秒进行时间间隔
$max_limit = 5;   // 5次
$key = 'slide_window_set';

$trace_id = gen_trace_id();

error_log('REQUEST BEGIN ' . $trace_id);

$current_microtime = microtime(true) * 1000 * 1000;
$current_window_startmicrotime = $current_microtime - $microtime_limit;

/**
 * 方式一
 * 并发大的情况会有超过限制的问题(可以使用jmeter压测查看)
 */

// 获取数量 并发的话，可能会导致超出限制
//$count = $redis->zCount($key, $current_window_startmicrotime, $current_microtime);
//if ($count + 1 > $max_limit) {
//    $redis->incr('slide_window_fail');
//    error_log('活动太火爆了，请稍后再试! ' . $trace_id);
//    error_log('---------------------------------------');
//    echo '活动太火爆了，请稍后再试! ' . $trace_id;
//    exit();
//}
//$redis->zAdd($key, array(), $current_microtime, $current_microtime);
//$redis->incr('slide_window_success');
//error_log('抽奖成功! ' . $trace_id);
//error_log('---------------------------------------');
//echo '抽奖成功! ' . $trace_id;

/**
 * 方式二
 * 使用 redis lua 做原子性 保证同时顺序执行 zcount 和 zadd
 */

$lua = <<<SCRIPT
local keyName  = KEYS[1]
local maxLimit = ARGV[1]
local minScore = ARGV[2]
local maxScore = ARGV[3]

local count = redis.call('zcount', keyName, minScore, maxScore)
if tonumber(count) >= tonumber(maxLimit)
then
    return false
else
     redis.call('zadd', keyName, maxScore, maxScore)
     redis.call('zremrangebyscore', keyName, 0, minScore)
     return true
end;
SCRIPT;

$lua_res = $redis->eval($lua, array($key, $max_limit, $current_window_startmicrotime, $current_microtime), 1);
if ($lua_res == false) {
    $redis->incr('slide_window_fail');
    error_log('活动太火爆了，请稍后再试! ' . $trace_id);
    error_log('---------------------------------------');
    echo '活动太火爆了，请稍后再试! ' . $trace_id;
    exit();
}

$redis->incr('slide_window_success');
error_log('抽奖成功! ' . $trace_id);
error_log('---------------------------------------');
echo '抽奖成功! ' . $trace_id;
